package com.qijian.maindata.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qijian.maindata.domain.query.StoreLocationNewQuery;
import com.qijian.maindata.domain.vo.StoreLocationNewExcelVo;
import com.qijian.maindata.domain.vo.StoreLocationNewImportExcelVo;
import com.qijian.common.annotation.Log;
import com.qijian.common.core.controller.BaseController;
import com.qijian.common.core.domain.AjaxResult;
import com.qijian.common.core.page.TableDataInfo;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.bean.BeanUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.common.utils.poi.ExcelUtil;
import com.qijian.maindata.domain.Store;
import com.qijian.maindata.domain.StoreLocationNew;
import com.qijian.maindata.domain.vo.StoreLocationNewVo;
import com.qijian.maindata.service.IStoreLocationNewService;
import com.qijian.maindata.service.IStoreService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 库位新Controller
 *
 * @author qijian
 * @date 2024-11-28
 */
@Api(tags = "库位新")
@RestController
@RequiredArgsConstructor
@RequestMapping("/business/storeLocation")
public class StoreLocationNewController extends BaseController {

    private final IStoreLocationNewService storeLocationNewService;

    private final IStoreService storeService;


    /**
     * 查询库位新列表
     */
    @GetMapping("/list")
    public TableDataInfo list(StoreLocationNewQuery query, Page<StoreLocationNew> page) {
        initOrderItem(StoreLocationNew.class, page.orders());
        return getDataTable(storeLocationNewService.selectPageVo(page, WhereEntityTool.invoke(query)));
    }

    /**
     * 导出库位新列表
     */
    @Log(title = "库位新", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(StoreLocationNewQuery query, HttpServletResponse response) {
        return new ExcelUtil<>(StoreLocationNewVo.class).exportExcel(storeLocationNewService.listVo(WhereEntityTool.invoke(query)), "库位数据");
    }

    /**
     * 获取库位新详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        StoreLocationNewVo StoreLocationNewVo = storeLocationNewService.getVoById(id);

        if (null != StoreLocationNewVo) {
            AjaxResult.error("当前库位无法获取/或已被关闭");
        }

        return AjaxResult.success(StoreLocationNewVo);
    }

    /**
     * 新增库位新
     */
    @Log(title = "库位新", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody StoreLocationNewVo storeLocationNew) {

        AjaxResult dupLocations = buildLocation(storeLocationNew);
        if (dupLocations != null) return dupLocations;

        return toAjax(storeLocationNewService.save(storeLocationNew));
    }

    @Nullable
    private AjaxResult buildLocation(StoreLocationNewVo storeLocationNew) {
        LocationInfo result = getLocationInfo(storeLocationNew.getFmStoreName(), storeLocationNew);
        storeLocationNew.setLocationName(result.locationStr);
        storeLocationNew.setLocationFullName(result.locationFullName);
        storeLocationNew.setFullName(result.fullName);

        List<String> dupLocations = storeLocationNewService.getDupFullName(Collections.singletonList(result.fullName), storeLocationNew.getId());
        if (CollectionUtils.isNotEmpty(dupLocations)) {
            return AjaxResult.error("EX01:库位:[" + dupLocations + "]在系统中存在或者未启用!");
        }
        return null;
    }

    /**
     * 修改库位新
     */
    @Log(title = "库位新", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody StoreLocationNewVo storeLocationNew) {
        AjaxResult dupLocations = buildLocation(storeLocationNew);
        if (dupLocations != null) return dupLocations;

        return toAjax(storeLocationNewService.updateById(storeLocationNew));
    }

    @Log(title = "库位导入", businessType = BusinessType.INSERT)
    @PostMapping("/import")
    @Transactional
    public AjaxResult importData(MultipartFile file) throws Exception {
        List<StoreLocationNewExcelVo> list = new ExcelUtil<>(StoreLocationNewExcelVo.class).importExcel(file.getInputStream());

        if (CollectionUtils.isEmpty(list)) {
            return AjaxResult.error("EX01:导入数据为空!");
        }
        Map<String, List<Long>> map = storeService.list().stream().collect(
                Collectors.groupingBy(Store::getName, Collectors.mapping(Store::getId, Collectors.toList())
                ));

        List<String> errStoreName = new ArrayList<>();
        List<String> fullNameList = new ArrayList<>();

        List<StoreLocationNew> locationList = new ArrayList<>();

        // 仓库检查
        for (StoreLocationNewExcelVo locationVo : list) {
            String storeName = locationVo.getFmStoreName();
            if (!map.keySet().contains(storeName)) {
                errStoreName.add(storeName);
            } else {
                StoreLocationNew location = new StoreLocationNew();
                BeanUtils.copyProperties(locationVo, location);
                LocationInfo result = getLocationInfo(locationVo.getFmStoreName(), location);

                location.setLocationName(result.locationStr);
                location.setLocationFullName(result.locationFullName);
                location.setFullName(result.fullName);
                location.setStoreId(map.get(storeName).get(0));
                locationList.add(location);
                //完整地址字典
                fullNameList.add(result.fullName);
            }
        }
        //仓库判断
        if (CollectionUtils.isNotEmpty(errStoreName)) {
            throw new ServiceException("EX01:数据导入异常,仓库:[" + errStoreName + "]不存在!");
        }
        //当前文件 库位是否重复
        Long size = fullNameList.stream().distinct().count();
        if (size != fullNameList.size()) {
            return AjaxResult.error("EX01:当前文件存在库位重复数据!");
        }
        // 库存和数据库库位判断
        List<String> dupLocations = storeLocationNewService.getDupFullName(fullNameList, null);

        if (CollectionUtils.isNotEmpty(dupLocations)) {
            return AjaxResult.error("EX01:库位:[" + dupLocations + "]在系统中存在或者未启用!");
        }

        //批量存储数据
        storeLocationNewService.saveBatch(locationList);
        return AjaxResult.success("导入成功");
    }


    @GetMapping("/importTemplate")
    public AjaxResult importTemplate() {
        return new ExcelUtil<>(StoreLocationNewImportExcelVo.class).importTemplateExcel("库位导入摸板");
    }

    @NotNull
    private static LocationInfo getLocationInfo(String storeName, StoreLocationNew location) {
        String locationStr = location.getFirstType() + "-" + location.getSecondType() + "-" + location.getThirdType();
        String locationFullName = location.getFactoryArea() + "-" + locationStr;
        String fullName = storeName + ":" + locationFullName;
        LocationInfo result = new LocationInfo(locationStr, locationFullName, fullName);
        return result;
    }

    private static class LocationInfo {
        public final String locationStr;
        public final String locationFullName;
        public final String fullName;

        public LocationInfo(String locationStr, String locationFullName, String fullName) {
            this.locationStr = locationStr;
            this.locationFullName = locationFullName;
            this.fullName = fullName;
        }
    }

}
